﻿#region Using directives

using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;
using System.Text;

#endregion

namespace Ndo
{
    public sealed class AvoidSynchronizeAttribute : Attribute
    { }
    public static class Synchronize<T>
        where T : class
    {
        public static T From(T target)
        {
            return From(target, target);
        }
        public static T From(T target, object syncRoot)
        {
            if (target == null || syncRoot == null)
                throw new ArgumentNullException();
            return (T)CI.Invoke(new object[] { target, syncRoot });
        }
        static readonly ConstructorInfo CI;

        static Synchronize()
        {
            CI = new SynchronizeFactory<T>(
                string.Format("Synchronize[{0}]{1}"
                ,typeof(T).FullName, BoxHelper.GetId())).CI;
        }
        public static object GetSyncRoot(T boxedObj)
        {
            if (!(boxedObj is ISynchronized<T>))
                throw new InvalidOperationException();
            return ((ISynchronized<T>)boxedObj).SyncRoot;
        }
        public static T GetTarget(T boxedObj)
        {
            if (!(boxedObj is ISynchronized<T>))
                throw new InvalidOperationException();
            return ((ISynchronized<T>)boxedObj).Target;
        }
    }
    public interface ISynchronized<T> : IBoxed<T>
    {
        object SyncRoot { get;}
    }
}
